home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / nr4subr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  4.7 KB  |  203 lines

  1. /*
  2.  * nr4subr.c:  subroutines for net/rom transport layer.
  3.  * Copyright 1989 by Daniel M. Frank, W9NK.  Permission granted for
  4.  * non-commercial distribution only.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "config.h"
  10. #ifdef NETROM
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "ax25.h"
  14. #include "netrom.h"
  15. #include "nr4.h"
  16. #include <ctype.h>
  17.  
  18. /* Get a free circuit table entry, and allocate a circuit descriptor.
  19.  * Initialize control block circuit number and ID fields.
  20.  * Return a pointer to the circuit control block if successful,
  21.  * NULLNR4CB if not.
  22.  */
  23. struct nr4cb *
  24. new_n4circ()
  25. {
  26.     int i ;
  27.     struct nr4cb *cb ;
  28.  
  29.     for (i = 0 ; i <  NR4MAXCIRC ; i++)        /* find a free circuit */
  30.         if (Nr4circuits[i].ccb == NULLNR4CB)
  31.             break ;
  32.  
  33.     if (i == NR4MAXCIRC)
  34.         return NULLNR4CB;
  35.  
  36.     Nr4circuits[i].ccb = (struct nr4cb *)mxallocw(sizeof(struct nr4cb));
  37.  
  38.     cb = Nr4circuits[i].ccb;
  39.     cb->mynum = i ;
  40.     cb->myid = Nr4circuits[i].cid ;
  41.  
  42.     /* set l4 inactivity timer to 30 mins */
  43.     cb->inactivity.func = (void (*) __ARGS((void *))) reset_nr4;
  44.     cb->inactivity.arg = cb;
  45.     set_timer(&cb->inactivity,900000L);
  46.  
  47.     return cb ;
  48. }
  49.  
  50. /* Set the window size for a circuit and allocate the buffers for
  51.  * the transmit and receive windows.  Set the control block window
  52.  * parameter.  Return 0 if successful, -1 if not.
  53.  */
  54. int
  55. init_nr4window(struct nr4cb *cb,unsigned window)
  56. {
  57.     if (window == 0 || window > NR4MAXWIN) /* reject silly window sizes */
  58.         window = 1;
  59.  
  60.     cb->txbufs =
  61.          (struct nr4txbuf *)cxallocw(window,sizeof(struct nr4txbuf));
  62.  
  63.     cb->rxbufs =
  64.          (struct nr4rxbuf *)cxallocw(window,sizeof(struct nr4rxbuf));
  65.  
  66.     cb->window = window ;
  67.  
  68.     return 0 ;
  69. }
  70.  
  71. /* Free a circuit.  Deallocate the control block and buffers, and
  72.  * increment the circuit ID.  No return value.
  73.  */
  74. void
  75. free_n4circ(struct nr4cb *cb)
  76. {
  77.     unsigned circ = cb->mynum;
  78.  
  79.     if (cb == NULLNR4CB)
  80.         return ;
  81.  
  82.     if (cb->txbufs != (struct nr4txbuf *)0)
  83.         xfree(cb->txbufs) ;
  84.  
  85.     if (cb->rxbufs != (struct nr4rxbuf *)0)
  86.         xfree(cb->rxbufs) ;
  87.  
  88.     stop_timer(&cb->inactivity);    /* stop it */
  89.  
  90.     /* Better be safe than sorry: */
  91.     free_q(&cb->txq) ;
  92.     free_q(&cb->rxq) ;
  93.  
  94.     xfree(cb) ;
  95.  
  96.     if (circ > NR4MAXCIRC)        /* Shouldn't happen. */
  97.         return ;
  98.  
  99.     Nr4circuits[circ].ccb = NULLNR4CB ;
  100.     Nr4circuits[circ].cid++ ;
  101.     return;
  102. }
  103.  
  104. /* See if any open circuit matches the given parameters.  This is used
  105.  * to prevent opening multiple circuits on a duplicate connect request.
  106.  * Returns the control block address if a match is found, or NULLNR4CB
  107.  * otherwise.
  108.  */
  109. struct nr4cb *
  110. match_n4circ(index, id, user, node)
  111. int index ;                    /* index of remote circuit */
  112. int id ;                    /* id of remote circuit */
  113. char *user ;    /* address of remote user */
  114. char *node ;    /* address of originating node */
  115. {
  116.     int i ;
  117.     struct nr4cb *cb ;
  118.  
  119.     for (i = 0 ; i < NR4MAXCIRC ; i++) {
  120.         if ((cb = Nr4circuits[i].ccb) == NULLNR4CB)
  121.             continue ;        /* not an open circuit */
  122.         if (cb->yournum == index && cb->yourid == id
  123.           && addreq(cb->remote.user,user)
  124.           && addreq(cb->remote.node,node))
  125.             return cb ;
  126.     }
  127.     /* if we get to here, we didn't find a match */
  128.     return NULLNR4CB ;
  129. }
  130.  
  131. /* Validate the index and id of a local circuit, returning the control
  132.  * block if it is valid, or NULLNR4CB if it is not.
  133.  */
  134. struct nr4cb *
  135. get_n4circ(index, id)
  136. int index ;                /* local circuit index */
  137. int id ;                /* local circuit id */
  138. {
  139.     struct nr4cb *cb ;
  140.  
  141.     if (index >= NR4MAXCIRC || (cb = Nr4circuits[index].ccb) == NULLNR4CB)
  142.         return NULLNR4CB ;
  143.  
  144.     return (cb->myid == id) ? cb : NULLNR4CB ;
  145. }
  146.  
  147. /* Return 1 if b is "between" (modulo the size of an unsigned char)
  148.  * a and c, 0 otherwise.
  149.  */
  150. int
  151. nr4between(unsigned a,unsigned b,unsigned c)
  152. {
  153.     return ((a <= b && b < c) || (c < a && a <= b) || (b < c && c < a)) ? 1 : 0;
  154. }
  155.  
  156. /* Set up default timer values, etc., in newly connected control block.
  157.  */
  158. void
  159. nr4defaults(struct nr4cb *cb)
  160. {
  161.     int i ;
  162.     struct timer *t ;
  163.  
  164.     if (cb == NULLNR4CB)
  165.         return ;
  166.  
  167.     /* Set up the ACK and CHOKE timers */
  168.  
  169.     set_timer(&cb->tack,Nr4acktime * 1000) ;
  170.     cb->tack.func = nr4ackit ;
  171.     cb->tack.arg = cb ;
  172.  
  173.     set_timer(&cb->tchoke,Nr4choketime * 1000) ;
  174.     cb->tchoke.func = nr4unchoke ;
  175.     cb->tchoke.arg = cb ;
  176.  
  177.     cb->rxpastwin = cb->window ;
  178.  
  179.     /* Don't actually set the timers, since this is done in nr4sbuf */
  180.     for (i = 0 ; i < cb->window ; i++) {
  181.         t = &cb->txbufs[i].tretry ;
  182.         t->func = nr4txtimeout ;
  183.         t->arg = cb ;
  184.     }
  185.     return;
  186. }
  187.  
  188. /* See if this control block address is valid */
  189.  
  190. int
  191. nr4valcb(struct nr4cb *cb)
  192. {
  193.     int i;
  194.  
  195.     if (cb != NULLNR4CB) {
  196.         for (i = 0 ; i < NR4MAXCIRC ; i++)
  197.             if (Nr4circuits[i].ccb == cb)
  198.                 return 1 ;
  199.     }
  200.     return 0 ;
  201. }
  202.  
  203. #endif /* NETROM */